// 登录校验中间件之授权中间件		auth：authorization 授权 认可
module.exports = options => {			//module.exports 导出模块， options即可添加参数
  const assert = require('http-assert')
  const jwt = require('jsonwebtoken')
  const AdminUser = require('../models/AdminUser')

	// 闭包
  return async (req, res, next) => {
		// 解释:authorization具体看下面，Bearer与token中间有空格，方便分隔，
		// 第一步：如果中间件接收到req.headers的Authorization，或者空字符串（可能是直接打开接口页，比如http://localhost:3000/admin/api/rest/articles，没有进行登录），先变成字符串String()  （写了小写string，报错了，haha） （中间是或 ||）两种情况
		// 第二步：split(’ ‘)空格切割 ['Bearer’，'eyJhbGciOiJIUzI1N..']
		// 第三步：pop()，数组切割最后一项并返回该项，该项赋值给token，正好获取到完整的token
		const token = String(req.headers.authorization || '').split(' ').pop()
		assert(token, 401, '请先登录')		//若获取不到token值，即为空字符串，则会弹出401状态码（报错），消息提示 请先登录
		
		const { id } = jwt.verify(token, req.app.get('secret'))	// 注意，本来写的是app.get('secret')，但因为是在函数中，所以前面加上req，也是获取app.js中的secret秘钥,从秘钥+token生成id
		assert(id, 401, '请先登录')//若获取不到id（id位对象中的某一属性），则会弹出401状态码（报错），消息提示 请先登录
		
		req.user = await AdminUser.findById(id)	//通过id（每一个列表List里面都有_id）是否寻找到AdminUser模型中的用户名，密码  ,复制到req.user（都要加前缀）
    assert(req.user, 401, '请先登录')//若获取不到req.user，则会弹出401状态码（报错），消息提示 请先登录
    await next()	//上面流程全部通过则继续下一步 next()  （一定要写）
  }
} 

		//console.log(token)	//eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVkZDBkZWU3MjlkYzlhZDlmYmE4MTVlZiIsImlhdCI6MTU3Mzk2OTY0OX0.f4rrPP_TPXWWzZCV5n1DIAJXBRuusQMtOgwmdQpKzs4

		// console.log({id})		//{ id: '5dd0dee729dc9ad9fba815ef' }


		//console.log(req.user)	//{ _id: 5dd0dee729dc9ad9fba815ef, username: 'admin', __v: 0 }

		// Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IjVkY2ZjYTBmNzNkOGQ3ZTM3YWU0ZTk1NiIsImlhdCI6MTU3MzkwNzMxN30.21NoMW569BBJCHWAvFY1A4btPvHarmDbsjWd2v50SB0